# coding:utf-8
class Hello(object):
    pass


h = Hello()

print(type(h))
print(type(Hello))
print(type(123))
print(type("yjc"))
print(
    "Python里class的定义是运行时动态创建的，而创建class的方法就是使用type()函数。"
    "type()函数既可以返回一个对象的类型，又可以创建出新的类型，比如，我们可以通过type()函数创建出Hello类："
)


def sub(self, x, y):
    return x - y


# 定义 add 函数
def add(self, x, y):
    return x + y


# 修改后的代码，确保 add 和 sub 函数都已定义
Hello2 = type("Hello2", (object,), {"add": add, "mysub": sub})
"""
要创建一个class对象，type()函数依次传入3个参数：

class的名称；
继承的父类集合，注意Python支持多重继承，如果只有一个父类，别忘了tuple的单元素写法；
class的方法名称与函数绑定。
"""

h = Hello2()
# 原代码中定义的方法名是'mysub'，而不是'my_sub'，这里将调用方法名修改为正确的'mysub'
# 并且在类定义中，添加的方法名是 'add'，所以这里可以正常调用
print(h.add(1, 2))
# 原代码试图调用 Hello2 类的 mysub 方法，但由于类定义时的方法名是 'mysub'，调用时需要确保方法名一致
print(h.mysub(2, 1))

print(type(h))
print(type(Hello2))


print("---------------------metaclass-------------------------")
"""
metaclass，直译为元类，简单的解释就是：
当我们定义了类以后，就可以根据这个类创建出实例，所以：先定义类，然后创建实例。
但是如果我们想创建出类呢？那就必须根据metaclass创建出类，所以：先定义metaclass，然后创建类。
连接起来就是：先定义metaclass，就可以创建类，最后创建实例。
所以，metaclass允许你创建类或者修改类。换句话说，你可以把类看成是metaclass创建出来的“实例”。
metaclass是Python面向对象里最难理解，也是最难使用的魔术代码。正常情况下，你不会碰到需要使用metaclass的情况，所以，以下内容看不懂也没关系，因为基本上你不会用到。
"""


# metaclass是类的模板，所以必须从`type`类型派生：
class ListMetaclass(type):
    def __new__(cls, name, base, attrs):
        attrs["add"] = lambda self, value: self.append(value)

        print(cls, "\n", name, "\n", base, "\n", attrs, "\n")
        return type.__new__(cls, name, base, attrs)


# 根据 metaclass 产生类
class MyList(list, metaclass=ListMetaclass):
    pass


# 类继承
class OtherList(MyList):
    pass


# 以上通过metaclass动态生成了MyList类，并增加了成员方法add()。
L = MyList()
L.add("3")
print(L)
